<?php

namespace Jinxing\Admin\Http\Controllers;

use Hash;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Jinxing\Admin\Helpers\Tree;
use Jinxing\Admin\Models\Admin;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Jinxing\Admin\Repositories\MenuRepository;
use Jinxing\Admin\Repositories\RoleRepository;
use Jinxing\Admin\Repositories\AdminRepository;
use Jinxing\Admin\Repositories\ConfigRepository;
use Jinxing\Admin\Repositories\RoleUserRepository;
use Jinxing\Admin\Repositories\AdminMenuRepository;
use Illuminate\Http\JsonResponse as JsonResponseAlias;
use Jinxing\Admin\Http\Requests\Admin\Admins\StoreRequest;
use Jinxing\Admin\Http\Requests\Admin\Admins\UpdateRequest;
use Jinxing\Admin\Http\Requests\Admin\Admins\DestroyRequest;
use Jinxing\Admin\Http\Requests\Admin\Common\UploadImageRequest;
use Jinxing\Admin\Http\Requests\Admin\Admins\UpdatePasswordRequest;

/**
 * Class AdminsController 后台管理员信息
 *
 * @package App\Http\Controllers\Admin
 */
class AdminsController extends Controller
{
    /**
     * @var RoleRepository
     */
    private $roleRepository;
    /**
     * @var RoleUserRepository
     */
    private $roleUserRepository;

    /**
     * @var MenuRepository
     */
    private $menuRepository;

    /**
     * @var string 上传文件地址
     */
    protected $dirname = 'public/avatar';

    /**
     * @var AdminMenuRepository
     */
    private $userMenuRepository;

    public function __construct(
        AdminRepository $adminRepository,
        RoleRepository $roleRepository,
        RoleUserRepository $roleUserRepository,
        MenuRepository $menuRepository,
        AdminMenuRepository $userMenuRepository
    )
    {
        $this->repository         = $adminRepository;
        $this->roleRepository     = $roleRepository;
        $this->roleUserRepository = $roleUserRepository;
        $this->menuRepository     = $menuRepository;
        $this->userMenuRepository = $userMenuRepository;
    }

    /**
     * 首页显示
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index()
    {
        $status = admin::getStatus();
        $roles  = [];
        // 角色信息
        if (config('admin.verify_permissions')) {
            if ($roles = $this->roleRepository->findAll([])) {
                $list = [];
                foreach ($roles as $role) {
                    $list[$role['id']] = $role['name'] . ' (' . $role['display_name'] . ')';
                }

                $roles = $list;
            }
        }

        return view('admin::admins.index', compact('status', 'roles'));
    }

    /**
     * 添加数据
     *
     * @param StoreRequest $request
     *
     * @return JsonResponseAlias
     * @throws \Littlebug\Repository\Exception
     */
    public function store(StoreRequest $request)
    {
        $data  = $request->all();
        $admin = $this->repository->create($data);
        // 添加角色
        if (config('admin.verify_permissions')) {
            $this->roleUserRepository->createUserRoles(Arr::get($admin, 'id'), Arr::get($data, 'role_ids'));
        }

        return $this->success($admin);
    }

    /**
     * 修改数据
     *
     * @param UpdateRequest $request
     *
     * @return JsonResponseAlias
     * @throws \Littlebug\Repository\Exception
     */
    public function update(UpdateRequest $request)
    {
        $data = $request->all();
        if (!Arr::get($data, 'password')) {
            unset($data['password']);
        }

        $this->repository->update(Arr::get($data, 'id'), $data);
        return $this->success();
    }

    /**
     * 删除数据
     *
     * @param DestroyRequest $request
     *
     * @return JsonResponseAlias
     * @throws \Littlebug\Repository\Exception
     */
    public function destroy(DestroyRequest $request)
    {
        $this->repository->delete($request->input('id'));
        return $this->success();
    }

    /**
     * 详情信息
     * @return \Illuminate\View\View
     */
    public function show()
    {
        $config = ConfigRepository::instance()->findBy(['name' => 'login'], 'config');
        return view('admin::admins.show', [
            'user'   => Auth::guard('admin')->user(),
            'config' => $config,
        ]);
    }

    /**
     * 修改图像
     *
     * @param UploadImageRequest $request
     *
     * @return JsonResponseAlias
     * @throws \Jinxing\Admin\Exception
     */
    public function uploadAvatar(UploadImageRequest $request)
    {
        $urls = $this->handleVueUpload($request);
        $user = Auth::guard('admin')->user();
        if ($user instanceof Admin) {
            Storage::delete(Str::replaceFirst('/storage/', 'public/', $user['avatar']));
            $user->update(['avatar' => $urls['url']]);
        }

        // 新增数据
        return $this->success($urls);
    }

    /**
     * 修改密码
     *
     * @param UpdatePasswordRequest $request
     *
     * @return JsonResponseAlias
     */
    public function updatePassword(UpdatePasswordRequest $request)
    {
        // 获取私钥
        $config      = ConfigRepository::instance()->findBy(['name' => 'login'], 'config');
        $private_key = Arr::get($config, 'private_key');

        // 获取密码
        $old_password          = decrypt_password($request->input('old_password'), $private_key);
        $password              = decrypt_password($request->input('password'), $private_key);
        $password_confirmation = decrypt_password($request->input('password_confirmation'), $private_key);

        if ($password_confirmation !== $password) {
            return $this->systemError('确认密码错误');
        }

        if ($password === $old_password) {
            return $this->systemError('新密码不能和旧密码一致');
        }

        // 验证密码是否一致
        $user = Auth::guard('admin')->user();
        if (!Hash::check($old_password, Arr::get($user, 'password'))) {
            return $this->systemError('旧密码错误');
        }

        // 修改密码
        $this->repository->update(['id' => $user['id']], ['password' => $password]);
        return $this->success();
    }

    /**
     * 分配菜单
     *
     * @param DestroyRequest $request
     *
     * @param Tree           $tree
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
     */
    public function menus(DestroyRequest $request, Tree $tree)
    {
        $id = (int)$request->get('id');
        if ($id == 1) {
            $request->session()->flash('error', trans('admin.notAllowedSetAdmin'));
            return redirect('/' . config('admin.route.prefix') . '/admins/index');
        }

        view()->share([
            'title'           => trans('分配权限'),
            '__active_menu__' => 'admin/admins/index',
        ]);

        $menus   = $this->menuRepository->findAll([]);
        $menuIds = $this->userMenuRepository->findAllBy(['user_id' => $id], 'menu_id');
        $arrTree = $tree->init([
            'parentIdName' => 'parent',
            'childrenName' => 'children',
            'array'        => $menus,
        ])->getTreeArray(0);
        $trees   = $this->menuRepository->getJsMenus($arrTree, $menuIds);
        return view('admin::admins.menus', compact('trees', 'menuIds', 'id'));
    }

    /**
     * 修改用户菜单
     *
     * @param DestroyRequest $request
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     * @throws \Throwable
     */
    public function updateMenus(DestroyRequest $request)
    {
        $idItems = $request->input('menu_ids');
        $userId  = $request->input('id');
        $this->userMenuRepository->updateUserMenus($userId, $idItems);
        return redirect('/' . config('admin.route.prefix') . '/admins/index');
    }
}
